﻿using System;
using System.Linq;
using Rhino.Etl.Core;
using Rhino.Etl.Core.Operations;

namespace Sqloogle.Operations {

    /// <summary>
    /// SqloogleCompare has the aweful job of determining what we should
    /// do with each freshly crawled and existing sql objects.  We'll end up
    /// with either a create, an update to dropped status, a None (no action)
    /// or a property update.
    /// </summary>
    public class SqloogleCompare : JoinOperation {

        protected override Row MergeRows(Row newRow, Row oldRow) {

            // if existing row doesn't exist, then fresh row is new, and should be created
            if (oldRow["id"] == null) {
                newRow["action"] = "Create";
                return newRow;
            }

            // if fresh row doesn't exist, then this existing row has been dropped, and so we mark as dropped and update
            if (newRow["id"] == null) {
                oldRow["dropped"] = true;
                oldRow["use"] = "0000000000";
                oldRow["count"] = "0000000000";
                oldRow["action"] = "Update";
                return oldRow;
            }

            // if fresh and existing rows are the same, then we have nothing to do.
            if (Equal(newRow, oldRow)) {
                oldRow["action"] = "None";
                return oldRow;
            }

            // same sql, but other properties have been updated, so we should update it.
            newRow["action"] = "Update";
            newRow["modified"] = DateTime.Today.ToString("yyyyMMdd");
            return newRow;
        }

        private static bool Equal(QuackingDictionary newRow, QuackingDictionary oldRow) {
            var fields = new string[] { "use", "lastused", "modified", "count", "created", "name", "server", "database", "schema", "dropped" };
            var allEqual = fields.All(field => newRow[field].Equals(oldRow[field]));
            return allEqual;
        }

        protected override void SetupJoinConditions() {
            FullOuterJoin.Left("id").Right("id");
        }

    }
}
